﻿using System;
using System.ComponentModel.Composition;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;



namespace ScrumFactory.Services.Logic.AuthProviders {

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]

    [Export(typeof(IAuthorizationProviderService))]
    [Export(typeof(IWindowsProviderService))]
    public class WindowsAuthorizationProvider : IWindowsProviderService, IAuthorizationProviderService {

        private string WindowsAutheticationServer {
            get {
                return System.Configuration.ConfigurationManager.AppSettings["WindowsAutheticationServer"];
            }
        }
    

        #region IAuthorizationProviderService Members

        public string ProviderName {
            get { return "Windows Authentication"; }
        }

        [WebInvoke(Method = "POST", UriTemplate = "WindowsAuthorization/{user}/", RequestFormat = WebMessageFormat.Json)]
        public string GetAuthorizationToken(string user, string password) {

            user = user.Replace("@@", "\\");
            PrincipalContext adContext;
            
            if(String.IsNullOrEmpty(WindowsAutheticationServer))
                adContext = new PrincipalContext(ContextType.Domain);
            else
                adContext = new PrincipalContext(ContextType.Domain, WindowsAutheticationServer);

            using (adContext) {
                
                if (!adContext.ValidateCredentials(user, password))
                    throw new WebFaultException(HttpStatusCode.Unauthorized);
            }
            return WindowsAuthenticationTicketStore.CreateTicket(user);
        }

        [WebGet(UriTemplate = "WindowsAuthorization/{user}/{token}/IsValid", RequestFormat = WebMessageFormat.Json)]
        public bool ValidadeToken(string token, string user) {

            return WindowsAuthenticationTicketStore.ValidateTicket(user, token);
        }

        public bool PasswordRequired {
            get {
                return true;
            }
        }

        public bool IsNetworkUser {
            get {
                return true;
            }
        }

        #endregion
    }

    public class WindowsAuthenticationTicketStore {

        private static Dictionary<string, WindowsAuthenticationTicket> Tickets = new Dictionary<string, WindowsAuthenticationTicket>();

        public static string CreateTicket(string user) {

            string oldTicket = GetTicketFor(user);
            if (oldTicket != null)
                Tickets.Remove(user);

            Tickets.Add(user, new WindowsAuthenticationTicket());
            return Tickets[user].Ticket;
        }

        public static string GetTicketFor(string user) {
            if (Tickets.ContainsKey(user) && Tickets[user].CreatedAt.AddDays(1) >= System.DateTime.Now)
                return Tickets[user].Ticket;

            return null;
        }

        public static bool ValidateTicket(string user, string ticketToValidate) {
            string ticket = GetTicketFor(user);
            if (ticket == null)
                return false;
            return ticket.Equals(ticketToValidate);
        }


        class WindowsAuthenticationTicket {

            public string Ticket { private set; get; }
            public DateTime CreatedAt { private set; get; }

            public WindowsAuthenticationTicket() {
                Ticket = Guid.NewGuid().ToString();
                CreatedAt = System.DateTime.Now;
            }
        }
    }
}
